home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Games / lptalk-1.3 / command.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  14KB  |  593 lines

  1. /************************************************************************/
  2. /* LP-Talk
  3.     Version 1.0 [ 9/24/90]
  4.     Version 1.1 [ 9/27/90]
  5. 27-Sep-90, shawnm, added delay to expanded macro transmission
  6.     Version 1.2 [ 9/28/90]
  7. */
  8. /* TinyTalk command line processing.                    */
  9. /*                                    */
  10. /*    Version 1.0 [ 1/25/90] : Initial implementation by ABR.        */
  11. /*        1.1 [ 1/26/90] : Added additional commands.        */
  12. /*        1.2 [ 1/26/90] : Added additional commands.        */
  13. /*        1.3 [ 2/ 2/90] : Yet more commands; use binary search.    */
  14. /*        1.4 [ 2/ 5/90] : A few more commands; world switching.    */
  15. /*        1.5 [ 2/ 5/90] : Fixed /savehilite | /loadhilite.    */
  16. /*                                    */
  17. /************************************************************************/
  18.  
  19. #include "tl.h"
  20. #include <stdio.h>
  21.  
  22. extern char *index();
  23. extern world_rec *find_world(), *get_default_world(), *get_world_header();
  24.  
  25.   /* There are enough commands now that a hash table or binary search */
  26.   /* is preferable.  We'll use a binary search.                  */
  27.  
  28. int handle_wrap_command(), handle_nowrap_command(), handle_log_command(),
  29.     handle_nolog_command(), handle_logme_command(), handle_def_command(),
  30.     handle_undef_command(), handle_savedef_command(), handle_nologme_command(),
  31.     handle_listdef_command(), handle_loaddef_command(),
  32.     handle_quiet_command(), handle_noquiet_command(), handle_login_command(),
  33.     handle_nologin_command(), handle_help_command(), handle_quit_command(),
  34.     handle_intr_command(), handle_nointr_command(), handle_beep_command(),
  35.     handle_nobeep_command(), handle_stty_command(), handle_nostty_command(),
  36.     handle_gag_command(), handle_nogag_command(), handle_savegag_command(),
  37.     handle_loadgag_command(), handle_listgag_command(),
  38.     handle_hilite_command(), handle_help2_command(), handle_recall_command(),
  39.     handle_nohilite_command(), handle_loadhilite_command(),
  40.     handle_savehilite_command(), handle_listhilite_command(),
  41.     handle_whisper_command(), handle_nowhisper_command(),
  42.     handle_listworlds_command(), handle_world_command();
  43.  
  44. int handle_macro_command();
  45.  
  46. typedef struct cmd_entry {
  47.   char *name;
  48.   int (*func)();
  49. } cmd_entry;
  50.  
  51.   /* It is IMPORTANT that the commands be in alphabetical order! */
  52.  
  53. static cmd_entry cmd_table[] =
  54. {
  55.   { "BEEP", handle_beep_command },
  56.   { "DEF", handle_def_command },
  57.   { "GAG", handle_gag_command },
  58.   { "HELP", handle_help_command },
  59.   { "HELP2", handle_help2_command },
  60.   { "HILITE", handle_hilite_command },
  61.   { "INTR", handle_intr_command },
  62.   { "LISTDEF", handle_listdef_command },
  63.   { "LISTGAG", handle_listgag_command },
  64.   { "LISTHILITE", handle_listhilite_command },
  65.   { "LISTWORLDS", handle_listworlds_command },
  66.   { "LOADDEF", handle_loaddef_command },
  67.   { "LOADGAG", handle_loadgag_command },
  68.   { "LOADHILITE", handle_loadhilite_command },
  69.   { "LOG", handle_log_command },
  70.   { "LOGIN", handle_login_command },
  71.   { "LOGME", handle_logme_command },
  72.   { "NOBEEP", handle_nobeep_command },
  73.   { "NOGAG", handle_nogag_command },
  74.   { "NOHILITE", handle_nohilite_command },
  75.   { "NOINTR", handle_nointr_command },
  76.   { "NOLOG", handle_nolog_command },
  77.   { "NOLOGIN", handle_nologin_command },
  78.   { "NOLOGME", handle_nologme_command },
  79.   { "NOQUIET", handle_noquiet_command },
  80.   { "NOSTTY", handle_nostty_command },
  81.   { "NOWHISPER", handle_nowhisper_command },
  82.   { "NOWRAP", handle_nowrap_command },
  83.   { "QUIET", handle_quiet_command },
  84.   { "QUIT", handle_quit_command },
  85.   { "RECALL", handle_recall_command },
  86.   { "SAVEDEF", handle_savedef_command },
  87.   { "SAVEGAG", handle_savegag_command },
  88.   { "SAVEHILITE", handle_savehilite_command },
  89.   { "STTY", handle_stty_command },
  90.   { "UNDEF", handle_undef_command },
  91.   { "WHISPER", handle_whisper_command },
  92.   { "WORLD", handle_world_command },
  93.   { "WRAP", handle_wrap_command }
  94. };
  95.  
  96. #define NUM_COMMANDS (sizeof(cmd_table) / sizeof(cmd_entry))
  97.  
  98. handle_command(cmd_line, is_config)
  99.   register char *cmd_line;
  100.   int is_config;
  101. {
  102.   string cmd, args;
  103.   register char *place;
  104.   int (*handler)(), (*binary_search())();
  105.  
  106.   place = index(cmd_line, ' ');
  107.   if (place == NULL) {
  108.     strcpy(cmd, cmd_line + 1);        /* Only have command.  Ignore '/'. */
  109.     args[0] = '\0';
  110.   }
  111.   else {
  112.     *place = '\0';            /* Get rid of the space.... */
  113.     strcpy(cmd, cmd_line + 1);
  114.     strcpy(args, place + 1);
  115.     *place = ' ';            /* Put the space back! */
  116.   }
  117.  
  118.   stripstr(cmd);
  119.   stripstr(args);
  120.  
  121.   if (cmd[0] == '\0')            /* Empty command, ignore it. */
  122.     return;
  123.  
  124.   handler = binary_search(cmd);
  125.  
  126.   if (handler != NULL)
  127.     (*handler)(args);
  128.   else
  129.     handle_macro_command(cmd, args);    /* Assume it's a macro. */
  130. }
  131.  
  132. int (*binary_search(cmd))()
  133.   register char *cmd;
  134. {
  135.   register int bottom, top, mid, value;
  136.  
  137.   bottom = 0;
  138.   top = NUM_COMMANDS - 1;
  139.  
  140.   while (bottom <= top) {
  141.     mid = bottom + ((top - bottom) / 2);
  142.     value = comparestr(cmd, cmd_table[mid].name);
  143.     if (value == 0)
  144.       return (cmd_table[mid].func);
  145.     else if (value < 0)
  146.       top = mid - 1;
  147.     else
  148.       bottom = mid + 1;
  149.   }
  150.  
  151.   return (NULL);
  152. }
  153.  
  154. handle_wrap_command(args)        /* Enable word wrap. */
  155.   register char *args;
  156. {
  157.   if (args[0] == '\0')            /* No arguments */
  158.     enable_wrap(0);
  159.   else {
  160.     if ((args[0] < '0') || (args[0] > '9')) /* Verify starts numeric. */
  161.       fprintf(stderr,"%% Invalid wrap value %s.\n", args);
  162.     else
  163.       enable_wrap(atoi(args));        /* If argument, use it. */
  164.   }
  165. }
  166.  
  167. handle_nowrap_command(args)        /* Disable word wrap. */
  168.   char *args;
  169. {
  170.   disable_wrap();
  171. }
  172.  
  173. handle_log_command(args)        /* Enable logging. */
  174.   char *args;
  175. {
  176.   enable_logging(args);
  177. }
  178.  
  179. handle_nolog_command(args)        /* Disable logging. */
  180.   char *args;
  181. {
  182.   disable_logging();
  183. }
  184.  
  185. handle_logme_command(args)        /* Enable input logging. */
  186.   char *args;
  187. {
  188.   enable_logme();
  189. }
  190.  
  191. handle_nologme_command(args)        /* Disable input logging. */
  192.   char *args;
  193. {
  194.   disable_logme();
  195. }
  196.  
  197. handle_def_command(args)        /* Define a macro. */
  198.   register char *args;
  199. {
  200.   register char *place;
  201.   string name, body;
  202.  
  203.   place = index(args, '=');
  204.   if (place == NULL) {
  205.     fprintf(stderr,"%% No '=' in macro definition.\n");
  206.     return;
  207.   }
  208.  
  209.   *place = '\0';
  210.   strcpy(name, args);
  211.   strcpy(body, place + 1);
  212.   stripstr(name);
  213.   stripstr(body);
  214.  
  215.   add_macro(name, body);
  216. }
  217.  
  218. handle_undef_command(args)        /* Undefine a macro. */
  219.   char *args;
  220. {
  221.   remove_macro(args);
  222. }
  223.  
  224. handle_savedef_command(args)        /* Save macro definitions. */
  225.   register char *args;
  226. {
  227.   if (args[0] == '\0')            /* No filename, use default. */
  228.     strcpy(args, "~/lptalk.macros");
  229.  
  230.   write_macros(args);
  231. }
  232.  
  233. handle_macro_command(cmd, args)        /* Invoke a macro. */
  234.   char *args;
  235. {
  236.   string expanded;
  237.   char *sending;
  238.   char *next;
  239.   char *place;
  240.  
  241.   process_macro(cmd, args, expanded);      /* Expand the body */
  242.   if (expanded[0] != '\0') {          /* Catch failure (or empty). */
  243.     place = next = expanded;
  244.     while(place != NULL) {
  245.         place = index(next, '\n');
  246.         sending = next;
  247.         if (place != NULL) {
  248.             *place = '\0';
  249.             next = ++place;
  250.         }
  251.         transmit(sending, strlen(sending)); /* and send it via link. */
  252.         transmit("\n", 1);
  253.         sleep(1);
  254.     }
  255.   }
  256. }
  257.  
  258. handle_quiet_command(args)        /* Turn on portal suppression. */
  259.   char *args;
  260. {
  261.   set_quiet();
  262. }
  263.  
  264. handle_noquiet_command(args)        /* Turn off portal suppression. */
  265.   char *args;
  266. {
  267.   clear_quiet();
  268. }
  269.  
  270. handle_login_command(args)        /* Turn on automatic login. */
  271.   char *args;
  272. {
  273.   enable_auto_login();
  274. }
  275.  
  276. handle_nologin_command(args)        /* Turn off automatic login. */
  277.   char *args;
  278. {
  279.   disable_auto_login();
  280. }
  281.  
  282. handle_help_command(args)        /* Give user some help. */
  283.   char *args;
  284. {
  285.   puts("% Summary of commands:");
  286.   puts("%   /WRAP      Enables word-wrap mode.");
  287.   puts("%   /NOWRAP    Disables word-wrap mode.");
  288.   puts("%");
  289.   puts("%   /LOG       Enables file logging.");
  290.   puts("%   /NOLOG     Disables file logging.");
  291.   puts("%   /LOGME     Enables keyboard input logging.");
  292.   puts("%   /NOLOGME   Disables keyboard input logging.");
  293.   puts("%");
  294.   puts("%   /QUIET     Prevents login messages from being displayed.");
  295.   puts("%   /NOQUIET   Allows login messages to be displayed.");
  296.   puts("%");
  297.   puts("%   /LOGIN     Enables automatic login.");
  298.   puts("%   /NOLOGIN   Prevents automatic login.");
  299.   puts("%");
  300.   puts("%   /DEF       Defines a macro.");
  301.   puts("%   /UNDEF     Undefines a macro.");
  302.   puts("%   /LISTDEF   Lists currently defined macros.");
  303.   puts("%   /LOADDEF   Reads macro definitions from a file.");
  304.   puts("%   /SAVEDEF   Saves macro definitions in a file.");
  305.   puts("%   /macro     Invokes a macro.");
  306.   puts("%");
  307.   puts("%   /HELP2     For more help.");
  308. }
  309.  
  310. handle_help2_command(args)        /* Give user some help. */
  311.   char *args;
  312. {
  313.   puts("% Summary of commands:");
  314.   puts("%   /QUIT      Quits LP-Talk.");
  315.   puts("%   /INTR      Enables control-C.");
  316.   puts("%   /NOINTR    Disnables control-C.");
  317.   puts("%");
  318.   puts("%   /BEEP      Enables beeps for tells.");
  319.   puts("%   /NOBEEP    Disables beeps for tells.");
  320.   puts("%");
  321.   puts("%   /STTY      Reads system's keyboard setup.");
  322.   puts("%   /NOSTTY    Uses default keyboard setup.");
  323.   puts("%");
  324.   puts("%   /GAG       Prevents messages from a user from being displayed.");
  325.   puts("%              Also /NOGAG, /LISTGAG, /LOADGAG, and /SAVEGAG.");
  326.   puts("%");
  327.   puts("%   /HILITE    Hilites messages from a user.  The special arguments");
  328.   puts("%              TELL and WHISPER enable hiliting for those.");
  329.   puts("%              Also /NOHILITE, /LISTHILITE, /LOADHILITE, and /SAVEHILITE.");
  330.   puts("%");
  331. }
  332.  
  333. handle_listdef_command(args)
  334.   char *args;
  335. {
  336.   if (args[0] != '\0') {
  337.     if (equalstr(args, "FULL"))
  338.       list_all_macros(TRUE);
  339.     else
  340.       fprintf(stderr,"%% The only option to /listdef is 'full'.\n");
  341.   }
  342.   else
  343.     list_all_macros(FALSE);
  344. }
  345.  
  346. handle_loaddef_command(args)
  347.   char *args;
  348. {
  349.   do_file_load("/DEF ", args, "~/lptalk.macros");
  350. }
  351.  
  352. handle_quit_command(args)
  353.   char *args;
  354. {
  355.   set_done();
  356. }
  357.  
  358. handle_beep_command(args)
  359.   register char *args;
  360. {
  361.   if (args[0] == '\0')            /* No arguments, default to 3 beeps */
  362.     set_beep(3);
  363.   else {
  364.     if ((args[0] < '0') || (args[0] > '9')) /* Verify starts numeric. */
  365.       fprintf(stderr,"%% Invalid beep count %s.\n", args);
  366.     else
  367.       set_beep(atoi(args));        /* If argument, use it. */
  368.   }
  369. }
  370.  
  371. handle_nobeep_command(args)
  372.   char *args;
  373. {
  374.   set_beep(0);
  375. }
  376.  
  377. handle_intr_command(args)
  378.   char *args;
  379. {
  380.   allow_interrupts();
  381. }
  382.  
  383. handle_nointr_command(args)
  384.   char *args;
  385. {
  386.   disallow_interrupts();
  387. }
  388.  
  389. handle_stty_command(args)
  390.   char *args;
  391. {
  392.   use_stty();
  393. }
  394.  
  395. handle_nostty_command(args)
  396.   char *args;
  397. {
  398.   no_use_stty();
  399. }
  400.  
  401. handle_gag_command(args)
  402.   char *args;
  403. {
  404.   if (args[0] == '\0')
  405.     enable_gagging();
  406.   else
  407.     add_gag(args);
  408. }
  409.  
  410. handle_nogag_command(args)
  411.   char *args;
  412. {
  413.   if (args[0] == '\0')
  414.     disable_gagging();
  415.   else
  416.     remove_gag(args);
  417. }
  418.  
  419. handle_listgag_command(args)
  420.   char *args;
  421. {
  422.   list_gag();
  423. }
  424.  
  425. handle_loadgag_command(args)
  426.   char *args;
  427. {
  428.   do_file_load("/GAG ", args, "~/lptalk.gag");
  429. }
  430.  
  431. handle_savegag_command(args)
  432.   char *args;
  433. {
  434.   save_gag(args);
  435. }
  436.  
  437. handle_hilite_command(args)
  438.   register char *args;
  439. {
  440.   if (args[0] == '\0')
  441.     enable_hiliting();
  442.   else if (equalstr(args, "TELL") || equalstr(args, "TELLS"))
  443.     enable_tell_hiliting();
  444.   else if (equalstr(args, "WHISPER") || equalstr(args, "WHISPERS"))
  445.     enable_whisper_hiliting();
  446.   else if (equalstr(args, "NOTELL") || equalstr(args, "NOTELLS"))
  447.     disable_tell_hiliting();
  448.   else if (equalstr(args, "NOWHISPER") || equalstr(args, "NOWHISPERS"))
  449.     disable_whisper_hiliting();
  450.   else
  451.     add_hilite(args);
  452. }
  453.  
  454. handle_nohilite_command(args)
  455.   register char *args;
  456. {
  457.   if (args[0] == '\0')
  458.     disable_hiliting();
  459.   else if (equalstr(args, "TELL") || equalstr(args, "TELLS"))
  460.     disable_tell_hiliting();
  461.   else if (equalstr(args, "WHISPER") || equalstr(args, "WHISPERS"))
  462.     disable_whisper_hiliting();
  463.   else
  464.     remove_hilite(args);
  465. }
  466.  
  467. handle_listhilite_command(args)
  468.   char *args;
  469. {
  470.   list_hilite();
  471. }
  472.  
  473. handle_loadhilite_command(args)
  474.   char *args;
  475. {
  476.   do_file_load("/HILITE ", args, "~/lptalk.hilite");
  477. }
  478.  
  479. handle_savehilite_command(args)
  480.   char *args;
  481. {
  482.   save_hilite(args);
  483. }
  484.  
  485.   /* Generic routine to load commands of a specified type from a file. */
  486.  
  487. do_file_load(cmd, args, default_name)
  488.   register char *cmd;
  489.   char *args, *default_name;
  490. {
  491.   register FILE *cmdfile;
  492.   int done;
  493.   string line;
  494.   char temp[20];            /* Big enough for any command. */
  495.   int length;
  496.  
  497.   length = strlen(cmd);            /* Length of expected command. */
  498.  
  499.   if (args[0] == '\0')            /* No filename, use default. */
  500.     strcpy(args, default_name);
  501.  
  502.   expand_filename(args);
  503.  
  504.   cmdfile = fopen(args, "r");
  505.   if (cmdfile == NULL)
  506.     fprintf(stderr,"%% Couldn't open file %s.\n", args);
  507.   else {
  508.     done = FALSE;
  509.  
  510.     while (!done) {
  511.       if (fgets(line, MAXSTRLEN, cmdfile) == NULL)
  512.     done = TRUE;
  513.       else {
  514.     if (line[0] != '\0')        /* Get rid of newline. */
  515.       line[strlen(line)-1] = '\0';
  516.  
  517.     if ((line[0] == '\0') || (line[0] == ';')) /* Blank or comment. */
  518.       continue;
  519.  
  520.     strncpy(temp, line, length);    /* Length of command (incl. space). */
  521.     temp[length] = '\0';        /* Terminate after command. */
  522.     if (!equalstr(temp, cmd)) {
  523.       fprintf(stderr,"%% Illegal line: %s.\n", line);
  524.       done = TRUE;
  525.     }
  526.     else {
  527.       handle_command(line,FALSE); /* Process this recursively. */
  528.     }
  529.       }
  530.     }
  531.  
  532.     fclose(cmdfile);
  533.   }
  534. }
  535.  
  536. handle_whisper_command(args)
  537.   char *args;
  538. {
  539.   disable_whisper_gagging();
  540. }
  541.  
  542. handle_nowhisper_command(args)
  543.   char *args;
  544. {
  545.   enable_whisper_gagging();
  546. }
  547.  
  548. handle_recall_command(args)
  549.   char *args;
  550. {
  551.   avoid_recall();            /* Don't recall this! */
  552.   do_keyboard_recall();            /* Recall last keyboard buffer. */
  553. }
  554.  
  555. handle_listworlds_command(args)
  556.   char *args;
  557. {
  558.   register world_rec *p;
  559.  
  560.   p = get_world_header();
  561.   while (p != NULL) {
  562.     printf("%% %s\n", p->world);
  563.     p = p->next;
  564.   }
  565. }
  566.  
  567. handle_world_command(args)
  568.   char *args;
  569. {
  570.   char *place, ch;
  571.   register world_rec *where;
  572.  
  573.   if (args[0] == '\0') {
  574.     where = get_default_world();
  575.     if (where == NULL) {
  576.       fprintf(stderr, "%% No default world is set.");
  577.       return;
  578.     }
  579.   }
  580.   else {
  581.     where = find_world(args);
  582.     if (where == NULL) {
  583.       fprintf(stderr, "%% The world %s is unknown.", args);
  584.       return;
  585.     }
  586.   }
  587.  
  588.   if (connect_to(where))
  589.     magic_login();
  590.   else
  591.     fprintf(stderr,"%% Connection to world %s failed.\n", where->world);
  592. }
  593.